package com.xbongbong.saas.service.impl;

import com.alibaba.fastjson.JSON;
import com.xbongbong.paas.domain.entity.PaasStageEntity;
import com.xbongbong.paas.domain.entity.StageProcessEntity;
import com.xbongbong.paas.enums.StageTypeEnum;
import com.xbongbong.saas.help.StageHelp;
import com.xbongbong.paas.model.StageProcessModel;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.saas.domain.entity.StageWorkEntity;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.model.StageWorkModel;
import com.xbongbong.saas.service.StageInitService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Service("stageInitService")
public class StageInitServiceImpl implements StageInitService {

    @Resource
    private StageHelp stageHelp;
    @Resource
    private StageProcessModel stageProcessModel;
    @Resource
    private StageWorkModel stageWorkModel;

    /**
     * 初始化阶段流程、阶段、阶段任务
     * 以下两个场景会触发初始化
     * 1. CRM或者线索应用初始化
     * 2. 新建客户、机会、线索表单
     *
     * @param corpid    公司id
     * @param businessType  业务类型
     * @param formId    表单id
     */
    @Override
    public void init(String corpid, Integer businessType, Long formId) {
        // 初始化阶段流程
        StageProcessEntity stageProcess = new StageProcessEntity();
        stageProcess.initStageProcess(corpid, formId, 0, 0);
        stageProcessModel.insert(stageProcess);
        Long stageProcessId = stageProcess.getId();

        // 初始化阶段
        List<PaasStageEntity> defaultStageList = stageHelp.getDefaultStage(businessType);
        defaultStageList.forEach(defaultStage -> {
            defaultStage.setId(null);
            defaultStage.setCorpid(corpid);
            // defaultStage.setCode(UUID.randomUUID().toString());
            defaultStage.setFormId(formId);
            defaultStage.setStageProcessId(stageProcessId);
            defaultStage.setAddTime(DateTimeUtil.getInt());
            defaultStage.setUpdateTime(DateTimeUtil.getInt());
        });
        stageHelp.saveStageList(SaasMarkEnum.SAAS.getCode(), businessType, defaultStageList, false);

        // 获取普通阶段的主键id列表作为结束阶段的allow_reactive_stage
        List<Long> ordinaryStageIdList = defaultStageList.stream()
                .filter(stage -> Objects.equals(stage.getType(), StageTypeEnum.ORDINARY_STAGE.getType()))
                .map(PaasStageEntity::getId)
                .collect(Collectors.toList());

        // 更新阶段的allow_reactive_stage字段
        defaultStageList.forEach(defaultStage -> {
            Integer stageType = defaultStage.getType();
            boolean isEndStage = Objects.equals(stageType, StageTypeEnum.SUCCESS_STAGE.getType())
                    || Objects.equals(stageType, StageTypeEnum.FAIL_STAGE.getType())
                    || Objects.equals(stageType, StageTypeEnum.CANCEL_STAGE.getType());
            if (isEndStage) {
                defaultStage.setAllowReactiveStage(JSON.parseArray(JSON.toJSONString(ordinaryStageIdList)));
                stageHelp.updateStageEntity(SaasMarkEnum.SAAS.getCode(), businessType, defaultStage);
            }
        });

        Integer stageBusinessType = XbbRefTypeEnum.transferBusinessTypeToStageType(businessType);
        List<StageWorkEntity> defaultWorkList = stageHelp.getDefaultStageWork(stageBusinessType);
        Map<String, List<StageWorkEntity>> defaultWorkMap = defaultWorkList.stream().collect(Collectors.groupingBy(StageWorkEntity::getStageCode));

        // 初始化阶段任务
        defaultStageList.forEach(defaultStage -> {
            // 这里能通过阶段code去匹配对于的阶段work是因为前面初始化阶段的时候没有重新生成默认阶段的code
            // 获取这个阶段下定义的默认的阶段任务
            List<StageWorkEntity> stageWorkList = defaultWorkMap.get(defaultStage.getCode());
            if (CollectionsUtil.isNotEmpty(stageWorkList)) {
                stageWorkList.forEach(stageWork -> {
                    stageWork.setId(null);
                    stageWork.setCorpid(corpid);
                    stageWork.setFormId(formId);
                    stageWork.setStageProcessId(defaultStage.getStageProcessId());
                    stageWork.setStageId(defaultStage.getId());
                    stageWork.setStageCode(defaultStage.getCode());
                    stageWork.setAddTime(DateTimeUtil.getInt());
                    stageWork.setUpdateTime(DateTimeUtil.getInt());
                });
                stageWorkModel.insertBatch(stageWorkList);
            }
        });
    }
}
